<template>
    <el-dialog :title="title" :visible.sync="dialogVisible" width="1440px" append-to-body class="purchase-detail-dialog" destroy-on-close>
        <div class="purchase-detail-header">
            <div>
                <span>日期：</span>
                <span class="purchase-detail-date">{{ params.create_time }}</span>
            </div>
            <div>
                <span>合同号：</span>
                <span>{{ params.batch_id }}</span>
            </div>
        </div>
        <div class="purchase-detail-header">
            <div>
                <span>购货方（甲方）：</span>
                <span class="purchase-detail-bold">{{ `She Curve Limited` }}</span>
            </div>
            <div>
                <span>供货方（乙方）：</span>
                <span>{{ params.supply_name }}</span>
            </div>
        </div>
        <el-table
            v-loading="loading"
            :data="tableData"
            border
            class="purchase-detail-table"
            style="width: 100%; margin-top: 16px"
            :span-method="tableSpanMethod"
            show-summary
            :summary-method="getSummaries"
            header-cell-class-name="purchase-detail-th"
            cell-class-name="purchase-detail-td"
            size="mini"
            max-height="580px"
        >
            <el-table-column prop="spu" label="工厂款号" min-width="80" align="center"></el-table-column>
            <el-table-column prop="product_name" label="商品名称" min-width="130" align="center"></el-table-column>
            <el-table-column prop="color" label="颜色" min-width="80" align="center"></el-table-column>
            <el-table-column label="尺码" align="center">
                <el-table-column prop="cup" label="杯型" min-width="70" align="center" v-if="showCupColumn"></el-table-column>
                <el-table-column v-for="size in sizes" :key="size" :label="size" :prop="'size_' + size" min-width="90" align="center">
                    <template slot-scope="scope">
                        <template v-if="showCupColumn && !scope.row.cupMerge">
                            <el-input-number
                                :controls="false"
                                v-model="scope.row.suggest_sku_nums"
                                size="mini"
                                style="width: 100%"
                                @change="updateTable(scope.row, 'number')"
                                v-if="canEdit"
                            ></el-input-number>
                            <span v-else>{{ scope.row['size_' + size] }}</span>
                        </template>
                        <template v-else>
                            <el-input-number
                                :controls="false"
                                v-model="scope.row['size_' + size]"
                                size="mini"
                                style="width: 100%"
                                @change="updateTable(scope.row, 'number')"
                                v-if="canEdit"
                            ></el-input-number>
                            <span v-else>{{ scope.row['size_' + size] }}</span>
                        </template>
                    </template>
                </el-table-column>
            </el-table-column>
            <el-table-column prop="total_number" label="数量合计" min-width="70" align="center"></el-table-column>
            <el-table-column prop="single_price" label="单价" min-width="90" align="center">
                <template slot-scope="scope">
                    <el-input-number :controls="false" v-model="scope.row.single_price" size="mini" style="width: 100%" @change="updateTable(scope.row, 'price')" v-if="canEdit"></el-input-number>
                    <span v-else>{{ scope.row.single_price }}</span>
                </template>
            </el-table-column>
            <el-table-column prop="total_amount" label="金额(元)" min-width="120" align="center"></el-table-column>
            <el-table-column prop="arrival_time" label="到货日期" min-width="70" align="center"></el-table-column>
            <el-table-column prop="remark" label="备注" min-width="70" align="center"></el-table-column>
        </el-table>

        <div slot="footer" class="dialo2-footer">
            <el-button type="default" size="small" @click="cancel">取消</el-button>
            <el-button type="warning" plain icon="el-icon-download" size="small" @click="exportExcel">导出Excel</el-button>
            <el-button type="primary" size="small" @click="generate" :disabled="!canEdit" :loading="saveLoading">确认下单</el-button>
        </div>
    </el-dialog>
</template>

<script>
import { contact_info, confirm_order } from '@/api/product'
import { parseTime } from '@/utils/quickadmin'
import ExcelJS from 'exceljs'
import { saveAs } from 'file-saver'
export default {
    name: 'DetailDialog',
    props: {
        value: {
            type: Boolean,
            default: false,
            required: true,
        },
        params: {
            type: Object,
            default: () => {},
        },
    },
    data() {
        return {
            sizes: [],
            // 遮罩层
            loading: true,
            saveLoading: false,
            // 总条数
            total: 0,
            // 表格数据
            tableData: [],
            pageInfo: {
                page: 1,
                limit: 10,
            },
            // 查询参数
            queryParams: {
                product_type: undefined,
                seller_sku: undefined,
                hot_type: undefined,
                spu: undefined,
                operate_id: undefined,
                supply_id: undefined,
                create_time: [],
                inventory_quantity: undefined,
                on_way_quantity: undefined,
                not_send_quantity: undefined,
                sku_1days: undefined,
                suggest_sku_nums: undefined,
            },
            isConfirm: false,
        }
    },

    computed: {
        showCupColumn() {
            // 有一个cup为空则 不显示cup列
            return this.tableData.every(item => !!item.cup)
        },
        canEdit() {
            // 下单前可编辑
            return this.params.confirm_status !== 2
        },
        title() {
            return `合同批次号详情`
        },
        dialogVisible: {
            get() {
                return this.value
            },
            set(val) {
                this.$emit('input', val)
            },
        },
    },
    mounted() {
        this.getDetail()
    },
    methods: {
        exportExcel() {
            const workbook = new ExcelJS.Workbook()
            const worksheet = workbook.addWorksheet('明细')

            // 1. 复合表头
            const sizeCount = this.sizes.length
            let firstRow, header
            if (this.showCupColumn) {
                // 显示杯型
                firstRow = ['工厂款号', '商品名称', '颜色', '尺码', ...Array(sizeCount).fill(''), '数量合计', '单价', '金额(元)', '到货日期', '备注']
                header = ['', '', '', '杯型', ...this.sizes, '', '', '', '', '']
            } else {
                // 不显示杯型
                firstRow = ['工厂款号', '商品名称', '颜色', '尺码', ...Array(sizeCount - 1).fill(''), '数量合计', '单价', '金额(元)', '到货日期', '备注']
                header = ['', '', '', ...this.sizes, '', '', '', '']
            }
            const colCount = firstRow.length

            // 2. 顶部信息两行，两端对齐（只合并左侧和右侧单元格，中间不合并）
            worksheet.addRow(Array(colCount).fill(''))
            worksheet.addRow(Array(colCount).fill(''))

            // 填充内容
            worksheet.getCell(1, 1).value = '日期：' + (parseTime(this.params.create_time, 'y/m/d') || '')
            worksheet.getCell(1, colCount - 1).value = '合同号：' + (this.params.batch_id || '')
            worksheet.getCell(2, 1).value = '购货方（甲方）：She Curve Limited'
            worksheet.getCell(2, colCount - 1).value = '供货方（乙方）：' + (this.params.supply_name || '')

            // 合并左侧A、B，右侧最后两列
            worksheet.mergeCells(1, 1, 1, 2)
            worksheet.mergeCells(1, colCount - 1, 1, colCount)
            worksheet.mergeCells(2, 1, 2, 2)
            worksheet.mergeCells(2, colCount - 1, 2, colCount)

            // 样式：左对齐
            worksheet.getCell(1, 1).alignment = { vertical: 'middle', horizontal: 'left' }
            worksheet.getCell(1, colCount - 1).alignment = { vertical: 'middle', horizontal: 'left' }
            worksheet.getCell(2, 1).alignment = { vertical: 'middle', horizontal: 'left' }
            worksheet.getCell(2, colCount - 1).alignment = { vertical: 'middle', horizontal: 'left' }

            // 日期标红
            worksheet.getCell(1, 1).font = { color: { argb: 'FFFF0000' }, bold: true, size: 13 }
            worksheet.getCell(1, colCount - 1).font = { bold: true, size: 13 }
            worksheet.getCell(2, 1).font = { bold: true, size: 13 }
            worksheet.getCell(2, colCount - 1).font = { bold: true, size: 13 }

            // 3. 表头
            worksheet.addRow(firstRow)
            worksheet.addRow(header)

            // 合并“尺码”表头（注意行号偏移）
            const headRowOffset = 2
            if (this.showCupColumn) {
                worksheet.mergeCells(headRowOffset + 1, 4, headRowOffset + 1, 4 + sizeCount)
            } else {
                worksheet.mergeCells(headRowOffset + 1, 4, headRowOffset + 1, 3 + sizeCount)
            }
            // 合并空表头（除去“尺码”合并区）
            for (let i = 1; i <= firstRow.length; i++) {
                if (this.showCupColumn) {
                    if (i >= 5 && i <= 4 + sizeCount) continue
                } else {
                    if (i >= 4 && i <= 3 + sizeCount) continue
                }
                if (!header[i - 1]) {
                    worksheet.mergeCells(headRowOffset + 1, i, headRowOffset + 2, i)
                }
            }

            // 4. 数据区
            this.tableData.forEach(row => {
                worksheet.addRow([
                    row.spu,
                    row.product_name,
                    row.color,
                    ...(this.showCupColumn ? [row.cup] : []), // 只在显示cup列时导出cup
                    ...this.sizes.map(size => row['size_' + size] || ''),
                    row.total_number,
                    row.single_price,
                    row.total_amount,
                    row.arrival_time,
                    row.remark,
                ])
            })

            // 5. 合计行
            const sums = this.getSummaries({
                columns: [
                    { property: 'spu' },
                    { property: 'product_name' },
                    { property: 'color' },
                    ...(this.showCupColumn ? [{ property: 'cup' }] : []), // 只在显示cup列时导出cup
                    ...this.sizes.map(size => ({ property: 'size_' + size })),
                    { property: 'total_number' },
                    { property: 'single_price' },
                    { property: 'total_amount' },
                    { property: 'arrival_time' },
                    { property: 'remark' },
                ],
                data: this.tableData,
            })
            worksheet.addRow(sums)

            // 6. 合并工厂款号、商品名称、颜色相同的单元格，并设置垂直居中
            const dataStartRow = headRowOffset + 3
            const mergeFields = ['spu', 'product_name', 'color']
            mergeFields.forEach((field, colIdx) => {
                let start = dataStartRow
                for (let i = 1; i < this.tableData.length; i++) {
                    if (this.tableData[i][field] !== this.tableData[i - 1][field]) {
                        if (i + dataStartRow - 1 > start) {
                            worksheet.mergeCells(start, colIdx + 1, i + dataStartRow - 1, colIdx + 1)
                        }
                        start = i + dataStartRow
                    }
                }
                // 最后一组
                if (this.tableData.length + dataStartRow - 1 > start) {
                    worksheet.mergeCells(start, colIdx + 1, this.tableData.length + dataStartRow - 1, colIdx + 1)
                }
            })

            // 合并数量合计、单价、金额(元)三列，按颜色分组
            const colorMap = {}
            this.tableData.forEach((row, idx) => {
                if (!colorMap[row.color]) colorMap[row.color] = []
                colorMap[row.color].push(idx)
            })
            // 找到这三列的索引
            let base = 3 + (this.showCupColumn ? 1 : 0) + this.sizes.length
            const cupMerge =  this.tableData.some(item=>item.cupMerge)
            const mergeCols = [base + 1, base + 2, base + 3] // 数量合计、单价、金额(元)的列号（1-based）
            Object.values(colorMap).forEach(indices => {
                if (!cupMerge && indices.length > 1) {
                    mergeCols.forEach(col => {
                        worksheet.mergeCells(indices[0] + dataStartRow, col, indices[indices.length - 1] + dataStartRow, col)
                    })
                }
            })

            // 6. 设置样式
            worksheet.eachRow((row, rowNumber) => {
                row.eachCell(cell => {
                    // 只对表头和数据区设置居中，顶部信息不处理
                    if (rowNumber > 2) {
                        cell.alignment = { vertical: 'middle', horizontal: 'center', wrapText: true }
                        // 边框
                        cell.border = {
                            top: { style: 'thin' },
                            left: { style: 'thin' },
                            bottom: { style: 'thin' },
                            right: { style: 'thin' },
                        }
                    }
                    // 表头和合计行背景色
                    if (rowNumber === headRowOffset + 1 || rowNumber === headRowOffset + 2 || rowNumber === worksheet.rowCount) {
                        cell.fill = {
                            type: 'pattern',
                            pattern: 'solid',
                            fgColor: { argb: 'FFF5F7FA' },
                        }
                        cell.font = { bold: true }
                    }
                })
            })

            // 8. 设置行高
            worksheet.getRow(1).height = 24
            worksheet.getRow(2).height = 24
            worksheet.getRow(worksheet.rowCount).height = 22

            //9. 自动列宽
            worksheet.columns.forEach(column => {
                let maxLength = 8
                column.eachCell({ includeEmpty: true }, cell => {
                    const len = cell.value ? cell.value.toString().length : 0
                    if (len > maxLength) maxLength = len
                })
                column.width = maxLength + 4
            })

            //10. 导出
            workbook.xlsx.writeBuffer().then(buffer => {
                saveAs(new Blob([buffer]), `合同批次号详情_${parseTime(new Date(), 'y-m-d h:i:s')}.xlsx`)
            })
        },
        cancel() {
            this.dialogVisible = false
            this.$emit('cancel')
        },
        // 确认下单
        generate() {
            this.saveLoading = true
            let sku_list
            if (this.showCupColumn) {
                sku_list = this.reverseTableDataWithCup(this.tableData)
            } else {
                sku_list = this.reverseTableDataNoCup(this.tableData)
            }
            const params = {
                batch_id: this.params.batch_id,
                sku_list: sku_list.filter(item => item.suggest_sku_nums>0),
            }
            confirm_order(params)
                .then(res => {
                    this.$message.success(res.msg)
                    this.dialogVisible = false
                    this.$emit('success')
                })
                .finally(() => {
                    this.saveLoading = false
                })
        },
        updateTable(row, type) {
            if (this.showCupColumn && !row.cupMerge) {
                if (type === 'price') {
                    this.tableData = this.tableData.map(item => {
                        if (row.color === item.color) {
                            item.single_price = parseFloat(row.single_price)
                        }
                        return item
                    })
                }
                this.tableData = this.formateTableData(this.tableData)
            } else {
                this.tableData = this.tableData.map(item => {
                    if (row.color === item.color) {
                        item.single_price = parseFloat(row.single_price)

                        item.total_number = this.sizes.reduce((sum, size) => {
                            sum += Number(item[`size_${size}`] || 0)
                            return sum
                        }, 0)
                        item.total_amount = parseFloat(item.total_number * item.single_price).toFixed(2)
                    }
                    return item
                })
            }
        },
        formateTableData(data) {
            const letter_arr = ['A','B','C','D','E','F','G','H','I','J','K','L','M']
            // 先按 color 分组，再按 cup 分组
            const colorMap = {}
            data.forEach(item => {
                item[`size_${item.size}`] = item.suggest_sku_nums
                if (!colorMap[item.color]) {
                    colorMap[item.color] = {}
                }
                if (!colorMap[item.color][item.cup]) {
                    colorMap[item.color][item.cup] = []
                }
                colorMap[item.color][item.cup].push(item)
            })

            // 合并每组
            const merged = []
            Object.keys(colorMap).forEach(color => {
                // 对cup分组进行排序
                const cupGroups = Object.keys(colorMap[color]).sort((a, b) => {
                    const idxA = letter_arr.indexOf(a)
                    const idxB = letter_arr.indexOf(b)
                    // 未找到的cup排在最后
                    return (idxA === -1 ? 99 : idxA) - (idxB === -1 ? 99 : idxB)
                })
                cupGroups.forEach(cup => {
                    const group = colorMap[color][cup]
                    // 数量合计
                    const total_number = group.reduce((sum, cur) => sum + Number(cur.suggest_sku_nums || 0), 0)
                    // 金额合计
                    const total_amount = group.reduce((sum, cur) => sum + Number(cur.suggest_sku_nums || 0) * Number(cur.single_price || 0), 0)
                    // 只保留每组第一个，合并数据
                    const mergedRow = { ...group[0] }
                    // 添加一个cup merge 标识
                    mergedRow.cupMerge = true
                    // 合并所有 size_${item.size} 字段
                    group.forEach(item => {
                        mergedRow[`size_${item.size}`] = item[`size_${item.size}`]
                    })
                    mergedRow.total_number = total_number
                    mergedRow.total_amount = total_amount.toFixed(2)
                    merged.push(mergedRow)
                })
            })
            return merged
        },
        formateTableDataNoCup(data) {
            // 1. 按 color 分组
            const colorMap = {}
            data.forEach(item => {
                item[`size_${item.size}`] = item.suggest_sku_nums
                if (!colorMap[item.color]) {
                    colorMap[item.color] = []
                }
                colorMap[item.color].push(item)
            })
            // 2. 计算每组的 total_number 和 total_amount，并赋值,，然后合并成一个对象
            const map = {}
            Object.values(colorMap).forEach(group => {
                // total_number: 数量合计
                const total_number = group.reduce((sum, cur) => sum + Number(cur.suggest_sku_nums || 0), 0)
                // total_amount: 金额合计
                const total_amount = group.reduce((sum, cur) => sum + Number(cur.suggest_sku_nums || 0) * Number(cur.single_price || 0), 0)
                group.forEach(item => {
                    item.total_number = total_number
                    item.total_amount = total_amount.toFixed(2)
                    if (!map[item.color]) {
                        map[item.color] = { ...item }
                    } else {
                        Object.assign(map[item.color], item)
                    }
                })
            })
            return Object.values(map)
        },
                reverseTableDataWithCup(tableData) {
            const result = []
            tableData.forEach(row => {
                this.sizes.forEach(size => {
                    const num = row[`size_${size}`]
                    if (num !== undefined && num !== null && num !== '') {
                        // 只还原有数量的尺码
                        const item = {
                            ...row,
                            size: size,
                            suggest_sku_nums: num,
                            seller_sku: `${row.spu}-${row.color}-${size}${row.cup}`,
                        }
                        // 删除所有 size_* 字段，避免冗余
                        this.sizes.forEach(s => delete item[`size_${s}`])
                        result.push(item)
                    }
                })
            })

            return result
        },
        reverseTableDataNoCup(tableData) {
            // sizes: 当前所有尺码数组，如 ['A', 'B', 'C']
            const result = []
            tableData.forEach(row => {
                this.sizes.forEach(size => {
                    const num = row[`size_${size}`]
                    if (num !== undefined && num !== null && num !== '') {
                        // 只还原有数量的尺码
                        const item = {
                            ...row,
                            size: size,
                            suggest_sku_nums: num,
                            seller_sku: `${row.spu}-${row.color}-${size}`,
                        }
                        // 删除 size_A、size_B...等字段，避免冗余
                        this.sizes.forEach(s => delete item[`size_${s}`])
                        // 只保留需要的字段
                        result.push(item)
                    }
                })
            })
            return result
        },
        // 详情
        getDetail() {
            this.loading = true
            const params = {
                batch_id: this.params.batch_id,
            }
            contact_info(params)
                .then(response => {
                    this.sizes = Array.from(new Set(response.data.map(item => item.size)))
                    const showCupColumn = response.data.every(item => !!item.cup)
                    if (showCupColumn) {
                        this.tableData = this.formateTableData(response.data)
                    } else {
                        this.tableData = this.formateTableDataNoCup(response.data)
                    }
                })
                .finally(() => {
                    this.loading = false
                })
        },
        // 合并单元格
        tableSpanMethod({ row, column, rowIndex, columnIndex }) {
            const len = this.sizes.length - 1 + (this.showCupColumn ? 1 : 0) + 3
            const inds = [0, 1, 2, len + 4, len + 5]
            if (inds.includes(columnIndex)) {
                if (rowIndex > 0 && this.tableData[rowIndex][column.property] === this.tableData[rowIndex - 1][column.property]) {
                    return [0, 0]
                }
                let rowspan = 1
                for (let i = rowIndex + 1; i < this.tableData.length; i++) {
                    if (this.tableData[i][column.property] === row[column.property]) {
                        rowspan++
                    } else {
                        break
                    }
                }
                return [rowspan, 1]
            }
            //  数量 单价 金额 需要特殊处理，如果颜色一样则，单价需要合并
            const extra = ['single_price', 'total_amount', 'total_number']
            if (extra.includes(column.property)) {
                if(row.cupMerge && ['total_amount', 'total_number'].includes(column.property)) {
                    return [1, 1]
                }
                // 只对第一个出现的 color 合并
                if (rowIndex > 0 && this.tableData[rowIndex].color === this.tableData[rowIndex - 1].color) {
                    return [0, 0]
                }
                let rowspan = 1
                for (let i = rowIndex + 1; i < this.tableData.length; i++) {
                    if (this.tableData[i].color === row.color) {
                        rowspan++
                    } else {
                        break
                    }
                }
                return [rowspan, 1]
            }
            return [1, 1]
        },
        getSummaries({ columns, data }) {
            const len = this.sizes.length - 1 + (this.showCupColumn ? 1 : 0) + 3
            const sums = []
            const empty = [this.showCupColumn ? 3 : 2, len + 2, len + 5, len + 8]
            columns.forEach((column, index) => {
                if (index === 0) {
                    sums[index] = '合计'
                    return
                } else if (empty.includes(index)) {
                    sums[index] = ''
                    return
                }
                const values = data.map(item => Number(item[column.property]))
                if (!values.every(value => isNaN(value))) {
                    sums[index] = values.reduce((prev, curr) => {
                        const value = Number(curr)
                        if (!isNaN(value)) {
                            return prev + curr
                        } else {
                            return prev
                        }
                    }, 0)
                    if (index === len + 3) {
                        sums[index] = '￥' + sums[index].toFixed(2)
                    }
                } else {
                    sums[index] = ''
                }
            })

            return sums
        },
    },
}
</script>

<style scoped>
/* .purchase-detail-dialog .el-dialog__body {
    padding: 16px 24px 24px 24px;
    background: #fff;
} */
.purchase-detail-header {
    display: flex;
    justify-content: space-between;
    margin-bottom: 4px;
    font-size: 15px;
}
.purchase-detail-header > div {
    flex: 1;
}
.purchase-detail-date {
    color: #e74c3c;
    font-weight: bold;
}
.purchase-detail-bold {
    font-weight: bold;
}
.purchase-detail-table {
    font-size: 14px;
}
.purchase-detail-th {
    background: #f5f7fa;
    font-weight: bold;
    text-align: center;
}
.purchase-detail-td {
    text-align: center;
}
</style>
